1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.base;
18  
19  import com.google.common.annotations.GwtCompatible;
20  import com.google.common.collect.Lists;
21  import com.google.common.testing.EqualsTester;
22  
23  import junit.framework.TestCase;
24  
25  import java.io.Serializable;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  /**
30   * Tests com.google.common.base.Suppliers.
31   *
32   * @author Laurence Gonsalves
33   * @author Harry Heymann
34   */
35  @GwtCompatible(emulated = true)
36  public class SuppliersTest extends TestCase {
37    public void testCompose() {
38      Supplier<Integer> fiveSupplier = new Supplier<Integer>() {
39        @Override
40        public Integer get() {
41          return 5;
42        }
43      };
44  
45      Function<Number, Integer> intValueFunction =
46          new Function<Number, Integer>() {
47            @Override
48            public Integer apply(Number x) {
49              return x.intValue();
50            }
51          };
52  
53      Supplier<Integer> squareSupplier = Suppliers.compose(intValueFunction,
54          fiveSupplier);
55  
56      assertEquals(Integer.valueOf(5), squareSupplier.get());
57    }
58  
59    public void testComposeWithLists() {
60      Supplier<ArrayList<Integer>> listSupplier
61          = new Supplier<ArrayList<Integer>>() {
62        @Override
63        public ArrayList<Integer> get() {
64          return Lists.newArrayList(0);
65        }
66      };
67  
68      Function<List<Integer>, List<Integer>> addElementFunction =
69          new Function<List<Integer>, List<Integer>>() {
70            @Override
71            public List<Integer> apply(List<Integer> list) {
72              ArrayList<Integer> result = Lists.newArrayList(list);
73              result.add(1);
74              return result;
75            }
76          };
77  
78      Supplier<List<Integer>> addSupplier = Suppliers.compose(addElementFunction,
79          listSupplier);
80  
81      List<Integer> result = addSupplier.get();
82      assertEquals(Integer.valueOf(0), result.get(0));
83      assertEquals(Integer.valueOf(1), result.get(1));
84    }
85  
86    static class CountingSupplier implements Supplier<Integer>, Serializable {
87      private static final long serialVersionUID = 0L;
88      transient int calls = 0;
89      @Override
90      public Integer get() {
91        calls++;
92        return calls * 10;
93      }
94    }
95  
96    public void testMemoize() {
97      CountingSupplier countingSupplier = new CountingSupplier();
98      Supplier<Integer> memoizedSupplier = Suppliers.memoize(countingSupplier);
99      checkMemoize(countingSupplier, memoizedSupplier);
100   }
101 
102   public void testMemoize_redudantly() {
103     CountingSupplier countingSupplier = new CountingSupplier();
104     Supplier<Integer> memoizedSupplier = Suppliers.memoize(countingSupplier);
105     assertSame(memoizedSupplier, Suppliers.memoize(memoizedSupplier));
106   }
107 
108   private void checkMemoize(
109       CountingSupplier countingSupplier, Supplier<Integer> memoizedSupplier) {
110     // the underlying supplier hasn't executed yet
111     assertEquals(0, countingSupplier.calls);
112 
113     assertEquals(10, (int) memoizedSupplier.get());
114 
115     // now it has
116     assertEquals(1, countingSupplier.calls);
117 
118     assertEquals(10, (int) memoizedSupplier.get());
119 
120     // it still should only have executed once due to memoization
121     assertEquals(1, countingSupplier.calls);
122   }
123 
124   public void testMemoizeExceptionThrown() {
125     Supplier<Integer> exceptingSupplier = new Supplier<Integer>() {
126       @Override
127       public Integer get() {
128         throw new NullPointerException();
129       }
130     };
131 
132     Supplier<Integer> memoizedSupplier = Suppliers.memoize(exceptingSupplier);
133 
134     // call get() twice to make sure that memoization doesn't interfere
135     // with throwing the exception
136     for (int i = 0; i < 2; i++) {
137       try {
138         memoizedSupplier.get();
139         fail("failed to throw NullPointerException");
140       } catch (NullPointerException e) {
141         // this is what should happen
142       }
143     }
144   }
145 
146   public void testOfInstanceSuppliesSameInstance() {
147     Object toBeSupplied = new Object();
148     Supplier<Object> objectSupplier = Suppliers.ofInstance(toBeSupplied);
149     assertSame(toBeSupplied,objectSupplier.get());
150     assertSame(toBeSupplied,objectSupplier.get()); // idempotent
151   }
152 
153   public void testOfInstanceSuppliesNull() {
154     Supplier<Integer> nullSupplier = Suppliers.ofInstance(null);
155     assertNull(nullSupplier.get());
156   }
157 
158   public void testSupplierFunction() {
159     Supplier<Integer> supplier = Suppliers.ofInstance(14);
160     Function<Supplier<Integer>, Integer> supplierFunction =
161         Suppliers.supplierFunction();
162 
163     assertEquals(14, (int) supplierFunction.apply(supplier));
164   }
165 
166   public void testOfInstance_equals() {
167     new EqualsTester()
168         .addEqualityGroup(
169             Suppliers.ofInstance("foo"), Suppliers.ofInstance("foo"))
170         .addEqualityGroup(Suppliers.ofInstance("bar"))
171         .testEquals();
172   }
173 
174   public void testCompose_equals() {
175     new EqualsTester()
176         .addEqualityGroup(
177             Suppliers.compose(Functions.constant(1), Suppliers.ofInstance("foo")),
178             Suppliers.compose(Functions.constant(1), Suppliers.ofInstance("foo")))
179         .addEqualityGroup(
180             Suppliers.compose(Functions.constant(2), Suppliers.ofInstance("foo")))
181         .addEqualityGroup(
182             Suppliers.compose(Functions.constant(1), Suppliers.ofInstance("bar")))
183         .testEquals();
184   }
185 }
186